Slovenščina

Poglobljena raziskava Tornada, spletnega ogrodja in asinhrone omrežne knjižnice v Pythonu. Naučite se graditi razširljive, visoko zmogljive aplikacije s podrobnimi razlagami, primeri in najboljšimi praksami.

Dokumentacija Tornado: Obsežen vodnik za razvijalce po vsem svetu

Tornado je spletno ogrodje v Pythonu in asinhrona omrežna knjižnica, prvotno razvita pri FriendFeed. Posebej je primeren za "long-polling", WebSockets in druge aplikacije, ki zahtevajo dolgotrajno povezavo z vsakim uporabnikom. Njegov neblokirajoči omrežni V/I (I/O) omogoča izjemno razširljivost in je močna izbira za gradnjo visoko zmogljivih spletnih aplikacij. Ta obsežen vodnik vas bo popeljal skozi osrednje koncepte Tornada in ponudil praktične primere za lažji začetek.

Kaj je Tornado?

V svojem jedru je Tornado spletno ogrodje in asinhrona omrežna knjižnica. Za razliko od tradicionalnih sinhronih spletnih ogrodij, Tornado uporablja arhitekturo z eno nitjo, ki temelji na zanki dogodkov. To pomeni, da lahko obravnava veliko sočasnih povezav, ne da bi potreboval nit za vsako povezavo, kar ga dela učinkovitejšega in bolj razširljivega.

Ključne značilnosti Tornada:

Postavitev vašega okolja za Tornado

Preden se potopite v razvoj s Tornadom, morate nastaviti svoje okolje. Tukaj je vodnik po korakih:

  1. Namestite Python: Prepričajte se, da imate nameščen Python 3.6 ali novejšo različico. Prenesete ga lahko z uradne spletne strani Python (python.org).
  2. Ustvarite virtualno okolje (priporočeno): Uporabite venv ali virtualenv za ustvarjanje izoliranega okolja za vaš projekt:
    python3 -m venv myenv
    source myenv/bin/activate  # V Linuxu/macOSu
    myenv\Scripts\activate  # V Windowsih
  3. Namestite Tornado: Namestite Tornado z uporabo pipa:
    pip install tornado

Vaša prva aplikacija Tornado

Ustvarimo preprosto "Pozdravljen, svet!" aplikacijo s Tornadom. Ustvarite datoteko z imenom app.py in dodajte naslednjo kodo:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Hello, World!")

def make_app():
 return tornado.web.Application([
  (r"/", MainHandler),
 ])

if __name__ == "__main__":
 app = make_app()
 app.listen(8888)
 tornado.ioloop.IOLoop.current().start()

Sedaj zaženite aplikacijo iz vašega terminala:

python app.py

Odprite spletni brskalnik in pojdite na http://localhost:8888. Videti bi morali sporočilo "Hello, World!".

Razlaga:

Obravnavalci zahtevkov in usmerjanje

Obravnavalci zahtevkov so temelj spletnih aplikacij Tornado. Določajo, kako obravnavati dohodne HTTP zahteve glede na URL. Usmerjanje preslika URL-je v specifične obravnavalce zahtevkov.

Definiranje obravnavalcev zahtevkov:

Za ustvarjanje obravnavalca zahtevkov podedujte razred tornado.web.RequestHandler in implementirajte ustrezne HTTP metode (get, post, put, delete, itd.).

class MyHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("This is a GET request.")

 def post(self):
  data = self.request.body.decode('utf-8')
  self.write(f"Received POST data: {data}")

Usmerjanje:

Usmerjanje se konfigurira pri ustvarjanju tornado.web.Application. Podate seznam parov (tuple), kjer vsak par vsebuje URL vzorec in pripadajoči obravnavalec zahtevkov.

app = tornado.web.Application([
 (r"/", MainHandler),
 (r"/myhandler", MyHandler),
])

URL vzorci:

URL vzorci so regularni izrazi. Uporabite lahko skupine regularnih izrazov za zajemanje delov URL-ja in jih posredujete kot argumente metodam obravnavalca zahtevkov.

class UserHandler(tornado.web.RequestHandler):
 def get(self, user_id):
  self.write(f"User ID: {user_id}")

app = tornado.web.Application([
 (r"/user/([0-9]+)", UserHandler),
])

V tem primeru se /user/([0-9]+) ujema z URL-ji, kot je /user/123. Del ([0-9]+) zajame eno ali več števk in jih posreduje kot argument user_id metodi get razreda UserHandler.

Predloge

Tornado vključuje preprost in učinkovit mehanizem za predloge. Predloge se uporabljajo za dinamično generiranje HTML-ja, ločevanje predstavitvene logike od aplikacijske logike.

Ustvarjanje predlog:

Predloge so običajno shranjene v ločenih datotekah (npr. index.html). Tukaj je preprost primer:

<!DOCTYPE html>
<html>
<head>
 <title>My Website</title>
</head>
<body>
 <h1>Welcome, {{ name }}!</h1>
 <p>Today is {{ today }}.</p>
</body>
</html>

{{ name }} in {{ today }} sta označbi za mesta, ki bosta ob izrisovanju predloge zamenjani z dejanskimi vrednostmi.

Izrisovanje predlog:

Za izrisovanje predloge uporabite metodo render() v vašem obravnavalcu zahtevkov:

class TemplateHandler(tornado.web.RequestHandler):
 def get(self):
  name = "John Doe"
  today = "2023-10-27"
  self.render("index.html", name=name, today=today)

Prepričajte se, da je nastavitev template_path pravilno konfigurirana v nastavitvah vaše aplikacije. Privzeto Tornado išče predloge v imeniku z imenom templates v istem imeniku kot vaša aplikacijska datoteka.

app = tornado.web.Application([
 (r"/template", TemplateHandler),
], template_path="templates")

Sintaksa predlog:

Predloge v Tornadu podpirajo različne funkcije, vključno z:

Asinhrone operacije

Moč Tornada je v njegovih asinhronih zmožnostih. Asinhrone operacije omogočajo vaši aplikaciji izvajanje neblokirajočega V/I, kar izboljša zmogljivost in razširljivost. To je še posebej uporabno za naloge, ki vključujejo čakanje na zunanje vire, kot so poizvedbe v bazi podatkov ali omrežne zahteve.

@tornado.gen.coroutine:

Dekorator @tornado.gen.coroutine vam omogoča pisanje asinhrone kode z uporabo ključne besede yield. To omogoča, da asinhrona koda izgleda in se obnaša bolj kot sinhrona koda, kar izboljša berljivost in vzdrževanje.

import tornado.gen
import tornado.httpclient

class AsyncHandler(tornado.web.RequestHandler):
 @tornado.gen.coroutine
 def get(self):
  http_client = tornado.httpclient.AsyncHTTPClient()
  response = yield http_client.fetch("http://example.com")
  self.write(response.body.decode('utf-8'))

V tem primeru je http_client.fetch() asinhrona operacija, ki vrne Future. Ključna beseda yield zaustavi izvajanje korutine, dokler se Future ne razreši. Ko je Future razrešen, se korutina nadaljuje in telo odgovora se zapiše odjemalcu.

tornado.concurrent.Future:

Future predstavlja rezultat asinhrone operacije, ki morda še ni na voljo. Objekte Future lahko uporabite za veriženje asinhronih operacij in obravnavanje napak.

tornado.ioloop.IOLoop:

IOLoop je srce asinhronega pogona Tornada. Spremlja datotečne deskriptorje in vtičnice za dogodke ter jih posreduje ustreznim obravnavalcem. Običajno vam ni treba neposredno komunicirati z IOLoop, vendar je pomembno razumeti njegovo vlogo pri obravnavanju asinhronih operacij.

WebSockets

Tornado nudi odlično podporo za WebSockets, kar omogoča komunikacijo v realnem času med strežnikom in odjemalci. WebSockets so idealni za aplikacije, ki zahtevajo dvosmerno komunikacijo z nizko zakasnitvijo, kot so klepetalnice, spletne igre in nadzorne plošče v realnem času.

Ustvarjanje obravnavalca WebSocket:

Za ustvarjanje obravnavalca WebSocket podedujte razred tornado.websocket.WebSocketHandler in implementirajte naslednje metode:

import tornado.websocket

class WebSocketHandler(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket odprt")

 def on_message(self, message):
  self.write_message(f"Poslali ste: {message}")

 def on_close(self):
  print("WebSocket zaprt")

 def check_origin(self, origin):
  return True # Omogoči med-izvorne WebSocket povezave

Integracija WebSocketov v vašo aplikacijo:

Dodajte obravnavalec WebSocket v konfiguracijo usmerjanja vaše aplikacije:

app = tornado.web.Application([
 (r"/ws", WebSocketHandler),
])

Implementacija na strani odjemalca:

Na strani odjemalca lahko uporabite JavaScript za vzpostavitev povezave WebSocket in pošiljanje/prejemanje sporočil:

const websocket = new WebSocket("ws://localhost:8888/ws");

websocket.onopen = () => {
 console.log("Povezava WebSocket vzpostavljena");
 websocket.send("Pozdrav od odjemalca!");
};

websocket.onmessage = (event) => {
 console.log("Prejeto sporočilo:", event.data);
};

websocket.onclose = () => {
 console.log("Povezava WebSocket zaprta");
};

Avtentikacija in varnost

Varnost je ključni vidik razvoja spletnih aplikacij. Tornado ponuja več funkcij, ki vam pomagajo zavarovati vaše aplikacije, vključno z avtentikacijo, avtorizacijo in zaščito pred pogostimi spletnimi ranljivostmi.

Avtentikacija:

Avtentikacija je postopek preverjanja identitete uporabnika. Tornado ponuja vgrajeno podporo za različne sheme avtentikacije, vključno z:

Avtorizacija:

Avtorizacija je postopek določanja, ali ima uporabnik dovoljenje za dostop do določenega vira. Logiko avtorizacije lahko implementirate v svojih obravnavalcih zahtevkov, da omejite dostop na podlagi vlog ali dovoljenj uporabnikov.

Najboljše varnostne prakse:

Uvedba (Deployment)

Uvedba aplikacije Tornado vključuje več korakov, vključno s konfiguracijo spletnega strežnika, nastavitvijo upravitelja procesov in optimizacijo zmogljivosti.

Spletni strežnik:

Tornado lahko uvedete za spletnim strežnikom, kot sta Nginx ali Apache. Spletni strežnik deluje kot obratni proksi (reverse proxy) in posreduje dohodne zahteve aplikaciji Tornado.

Upravitelj procesov:

Upravitelj procesov, kot sta Supervisor ali systemd, se lahko uporablja za upravljanje procesa Tornado, kar zagotavlja, da se samodejno ponovno zažene, če se sesuje.

Optimizacija zmogljivosti:

Internacionalizacija (i18n) in lokalizacija (l10n)

Pri gradnji aplikacij za globalno občinstvo je pomembno upoštevati internacionalizacijo (i18n) in lokalizacijo (l10n). i18n je proces oblikovanja aplikacije tako, da jo je mogoče brez inženirskih sprememb prilagoditi različnim jezikom in regijam. l10n je proces prilagajanja internacionalizirane aplikacije za določen jezik ali regijo z dodajanjem lokalno specifičnih komponent in prevajanjem besedila.

Tornado in i18n/l10n

Tornado sam po sebi nima vgrajenih knjižnic za i18n/l10n. Vendar pa lahko enostavno integrirate standardne knjižnice Pythona, kot je `gettext`, ali bolj sofisticirana ogrodja, kot je Babel, za obravnavo i18n/l10n znotraj vaše aplikacije Tornado.

Primer z uporabo `gettext`:

1. **Nastavite svoje lokalizacije:** Ustvarite imenike za vsak jezik, ki ga želite podpreti, ki vsebujejo kataloge sporočil (običajno datoteke `.mo`).

locales/
 en/LC_MESSAGES/messages.mo
 fr/LC_MESSAGES/messages.mo
 de/LC_MESSAGES/messages.mo

2. **Izvlecite prevodljive nize:** Uporabite orodje, kot je `xgettext`, da izvlečete prevodljive nize iz vaše kode Python v datoteko `.po` (Portable Object). Ta datoteka bo vsebovala originalne nize in označbe za prevode.

xgettext -d messages -o locales/messages.po your_tornado_app.py

3. **Prevedite nize:** Prevedite nize v datotekah `.po` za vsak jezik.

4. **Prevedite prevode:** Prevedite datoteke `.po` v datoteke `.mo` (Machine Object), ki jih `gettext` uporablja med izvajanjem.

msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo

5. **Integrirajte v vašo aplikacijo Tornado:**

import gettext
import locale
import os
import tornado.web

class BaseHandler(tornado.web.RequestHandler):
 def initialize(self):
  try:
  locale.setlocale(locale.LC_ALL, self.get_user_locale().code)
  except locale.Error:
  # Obravnavanje primerov, ko lokalizacija ni podprta s strani sistema
  print(f"Lokalizacija {self.get_user_locale().code} ni podprta")

  translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
  translation.install()
  self._ = translation.gettext

 def get_current_user_locale(self):
  # Logika za določanje uporabnikove lokalizacije (npr. iz glave Accept-Language, uporabniških nastavitev itd.)
  # To je poenostavljen primer - potrebovali boste bolj robustno rešitev
  accept_language = self.request.headers.get('Accept-Language', 'en')
  return tornado.locale.get(accept_language.split(',')[0].split(';')[0])

class MainHandler(BaseHandler):
 def get(self):
  self.render("index.html", _=self._)

settings = {
 "template_path": os.path.join(os.path.dirname(__file__), "templates"),
}

app = tornado.web.Application([
 (r"/", MainHandler),
], **settings)

6. **Spremenite svoje predloge:** Uporabite funkcijo `_()` (povezano z `gettext.gettext`), da označite nize za prevajanje v svojih predlogah.

<h1>{{ _("Dobrodošli na naši spletni strani!") }}</h1>
<p>{{ _("To je preveden odstavek.") }}</p>

Pomembni premisleki za globalno občinstvo:

Napredne teme

Strani z napakami po meri:

Prilagodite lahko strani z napakami, ki jih Tornado prikaže, ko pride do napake. To vam omogoča, da zagotovite bolj uporabniku prijazno izkušnjo in vključite informacije za odpravljanje napak.

Nastavitve po meri:

V konfiguraciji aplikacije lahko definirate nastavitve po meri in do njih dostopate v svojih obravnavalcih zahtevkov. To je uporabno za shranjevanje parametrov, specifičnih za aplikacijo, kot so povezovalni nizi za bazo podatkov ali ključi API.

Testiranje:

Temeljito testirajte svoje aplikacije Tornado, da zagotovite njihovo pravilno in varno delovanje. Uporabite enotske teste, integracijske teste in teste od konca do konca, da pokrijete vse vidike vaše aplikacije.

Zaključek

Tornado je močno in vsestransko spletno ogrodje, ki je zelo primerno za gradnjo razširljivih, visoko zmogljivih spletnih aplikacij. Njegova asinhrona arhitektura, podpora za WebSockets in enostaven API ga delajo za priljubljeno izbiro med razvijalci po vsem svetu. Z upoštevanjem smernic in primerov v tem obsežnem vodniku lahko začnete graditi lastne aplikacije Tornado in izkoristite njegove številne funkcije.

Ne pozabite se posvetovati z uradno dokumentacijo Tornada za najnovejše informacije in najboljše prakse. Veselo kodiranje!